/*
 * Copyright 2013 Walter Lütgenau.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package offset.nodes.client.model;

import java.io.Serializable;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 *
 * @author Walter Lütgenau
 */
public class CollectionServer implements Server {
    Server base;
    List<Request> requests = new ArrayList<Request>();
    
    class Request {
        ServerRequest request;
        ResponseHandler responseHandler;

        public Request(ServerRequest request, ResponseHandler responseHandler) {
            this.request = request;
            this.responseHandler = responseHandler;
        }

        public ServerRequest getRequest() {
            return request;
        }

        public ResponseHandler getResponseHandler() {
            return responseHandler;
        }
    }
    
    /**
     * Add a request to the stored requests.
     * 
     * These requests will be sent, once a call to "sendRequest" is made.
     * 
     * @param request the request
     * @param responseHandler the handler for the corresponding response
     */
    public void addRequest(ServerRequest request, ResponseHandler responseHandler) {
        requests.add(new Request(request, responseHandler));
    }
    
    public CollectionServer(Server base) {
        this.base = base;
    }

    /**
     * Add stored request to collection request first, then the new request.
     * Send all requests to the server and process the responses, except for the
     * last response. Return the last response.
     * 
     * @param request the new request
     * @return the last response
     * @throws Exception 
     */
    @Override
    public Serializable sendRequest(Serializable request) throws Exception {
        if (requests.size() == 0 || !(request instanceof ServerRequest))
            return base.sendRequest(request);
        
        CollectionRequest collectionRequest = new CollectionRequest();
        for (Request r : requests) 
            collectionRequest.addRequest(r.getRequest());
        collectionRequest.addRequest((ServerRequest) request);
        
        CollectionResponse collectionResponse = (CollectionResponse) base.sendRequest(collectionRequest);
        Iterator<ServerResponse> responseIterator = collectionResponse.getServerResponses();
        Iterator<Request> requestIterator = requests.iterator();
        
        while (requestIterator.hasNext()) {
            Request r = requestIterator.next();
            
            ServerResponse response = null;
            if (responseIterator.hasNext())
                response = responseIterator.next();
            r.getResponseHandler().handleResponse(response);
        }
        
        Serializable response = null;
        if (responseIterator.hasNext()) {
            response = responseIterator.next();
        }
        
        return response;
    }

    @Override
    public URL getURL() {
        return base.getURL();
    }
    
}
